package com.snail.snailvr.utils;

import android.app.NotificationManager;
import android.content.Context;
import android.text.TextUtils;

import com.activeandroid.ActiveAndroid;
import com.activeandroid.query.Delete;
import com.activeandroid.query.Select;
import com.snail.snailvr.R;
import com.snail.snailvr.event.BusProvider;
import com.snail.snailvr.event.OauthSuccessEvent;
import com.snail.snailvr.model.ConnectPc;
import com.snail.snailvr.model.FileIndex;
import com.snail.snailvr.model.History;
import com.snail.snailvr.model.InputItem;
import com.snail.snailvr.model.VideoInfo;
import com.snail.snailvr.network.providers.downloads.DownloadManager;
import com.snail.snailvr.network.providers.downloads.DownloadHelper;

import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Single;
import rx.SingleSubscriber;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * //TODO 把所有Subscription的返回值改成Observable<?>
 * 数据库操作集合类
 * Created by snail on 16/4/19.
 */
public class DatabaseUtils {
    /**
     * 保存首页下载列表
     *
     * @param videoInfoList
     */
    public static void saveDownloadList(final List<VideoInfo> videoInfoList) {
        Single.create(new Single.OnSubscribe<List<VideoInfo>>() {
            @Override
            public void call(SingleSubscriber<? super List<VideoInfo>> singleSubscriber) {
                ActiveAndroid.beginTransaction();

                try {
                    for (VideoInfo videoInfo : videoInfoList) {
                        videoInfo.save();
                        videoInfo.releaseMediaRetriever();
                    }
                    ActiveAndroid.setTransactionSuccessful();
                } finally {
                    ActiveAndroid.endTransaction();
                }
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    /**
     * 获取数据库保存的下载列表并且过滤已经删除的视频
     *
     * @param subscriber
     */
    public static Subscription getAllDownloads(Subscriber subscriber) {
        return Observable.create(new Observable.OnSubscribe<VideoInfo>() {
            @Override
            public void call(Subscriber<? super VideoInfo> subscriber) {
                final List<VideoInfo> list;
//                if(ActiveAndroid.getDatabase().getVersion()==23&&!SharedPreferencesUtil.getInstance().isDatabaseUpdated()){
//                    list = new Select().from(VideoInfo.class).orderBy("video_id desc").execute();
//                    initDownloadBeginTime(list);
//                    SharedPreferencesUtil.getInstance().databaseUpdated();
//                }else {
                    list = new Select().from(VideoInfo.class).orderBy(VideoInfo.COLUMN_DOWNLOAD_BEGIN+" desc").execute();
//                }
                LogUtils.d("list size=" + list.size());
                if (!subscriber.isUnsubscribed()) {
                    if (list != null) {

                        for (VideoInfo videoInfo : list) {
                            subscriber.onNext(videoInfo);
                            LogUtils.d("video  database="+videoInfo.getVideoId());
                        }
                        subscriber.onCompleted();
                    } else {
                        subscriber.onError(new Throwable("get all downloads error"));
                    }
                }
            }
        }).distinct().filter(new Func1<VideoInfo, Boolean>() {
            @Override
            public Boolean call(VideoInfo videoInfo) {
                if (videoInfo.getDownloadState() == DownloadManager.STATUS_SUCCESSFUL && !FileUtil.isFileExist(videoInfo.getVideoPath())) {
                    //TODO 需要优化
                    LogUtils.d("delete video"+videoInfo.getVideoPath());
                    //如果此視頻在文件夾中被刪除則需要同步刪除數據庫信息
                    new Delete().from(VideoInfo.class).where(VideoInfo.COLUMN_VIDEO_ID+" = ?", videoInfo.getVideoId()).execute();
                    DownloadHelper.getDownloadManager().remove(videoInfo.getVideoId());
                    return false;
                }
                return true;
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);


    }

    /**
     * 上级数据库 初始化新加入的字段
     * @param list
     */
    private static void initDownloadBeginTime(List<VideoInfo> list) {
        if(list!=null){
            int size=list.size();
            for(int i=0;i<size;i++){
                VideoInfo videoInfo=list.get(i);
                videoInfo.setDownloadBeginTime(System.currentTimeMillis()+1);
//                videoInfo.save();
            }
        }
    }


    /**
     * 根据videoId删除指定的视频文件
     *
     * @param videoInfo
     */
    public static void deleteVideo(final Context context, final VideoInfo videoInfo) {
        Single.create(new Single.OnSubscribe<VideoInfo>() {
            @Override
            public void call(SingleSubscriber<? super VideoInfo> singleSubscriber) {
                new Delete().from(VideoInfo.class)
                        .where("video_id = ?", videoInfo.getVideoId())
                        .execute();
                if (!singleSubscriber.isUnsubscribed()) {
                    if (FileUtil.deleteFile(videoInfo.getVideoPath()))
                        singleSubscriber.onSuccess(videoInfo);
                    else {
                        singleSubscriber.onError(new Throwable("delete file error"));
                    }
                }
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleSubscriber<VideoInfo>() {
            @Override
            public void onSuccess(VideoInfo value) {
                FileUtil.refreshMediaStore(value.getVideoPath());
                NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.cancel((int) videoInfo.getVideoId());
            }

            @Override
            public void onError(Throwable error) {

            }
        });

    }

    /**
     * 获取播放列表并且过滤已经删除的视频
     *
     * @return
     */
    public static Subscription getPlayHistory(Subscriber subscriber) {
        return Observable.create(new Observable.OnSubscribe<History>() {
            @Override
            public void call(Subscriber<? super History> subscriber) {

                final List<History> list = new Select().from(History.class).orderBy("id desc").execute();
                if (!subscriber.isUnsubscribed()) {
                    if (list != null) {
                        for (History history : list) {
                            LogUtils.d("history=" + history.toString());
                            if(!TextUtils.isEmpty(history.getPath()))
                                subscriber.onNext(history);
                        }
                        subscriber.onCompleted();
                    } else {
                        subscriber.onError(new Throwable("get all downloads error"));
                    }
                }
            }
        }).filter(new Func1<History, Boolean>() {
            @Override
            public Boolean call(History history) {
                if (!FileUtil.isFileExist(history.getPath())) {
                    new Delete().from(History.class).where("video_path = ?", history.getPath()).execute();
                    return false;
                }
                return true;
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);


    }

    /**
     * 清除播放历史记录
     */
    public static void clearHistory() {
        Single.create(new Single.OnSubscribe<Boolean>() {
            @Override
            public void call(SingleSubscriber<? super Boolean> singleSubscriber) {
                new Delete().from(History.class).execute();
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    /**
     * 所有网盘
     *
     * @param subscriber
     * @return
     */
    public static Subscription getAllNetDisk(SingleSubscriber subscriber) {

        return Single.create(new Single.OnSubscribe<List<InputItem>>() {
            @Override
            public void call(SingleSubscriber<? super List<InputItem>> singleSubscriber) {

                final List<InputItem> list = new Select().from(InputItem.class).execute();

                if (list != null && !list.isEmpty()) {
                    singleSubscriber.onSuccess(list);
                } else {
                    singleSubscriber.onError(new Throwable("get connected disk error"));
                }
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);

    }

    /**
     * 获取登录的网盘账户名称
     */
    public static Subscription getConnectedNetDiskAccountName(final String netDisk, SingleSubscriber subscriber) {
        return Single.create(new Single.OnSubscribe<String>() {

            @Override
            public void call(SingleSubscriber<? super String> singleSubscriber) {
                List<InputItem> list = new Select().from(InputItem.class).where("disk_type = ?", netDisk).execute();

                if (list != null && list.size() > 0) {
                    singleSubscriber.onSuccess(list.get(0).getTitle());
                } else {
                    singleSubscriber.onError(new Throwable("get connected account name error"));
                }
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取文件索引
     */
    public static Subscription getFileIndex(final String file_name, SingleSubscriber subscriber) {

        return Single.create(new Single.OnSubscribe<Integer>() {
            @Override
            public void call(SingleSubscriber<? super Integer> singleSubscriber) {
                List<FileIndex> list = new Select().from(FileIndex.class).where("file_name = ?", file_name).execute();

                if (list != null) {
                    if (list.size() > 0)//有
                    {
                        singleSubscriber.onSuccess(list.get(0).getFile_index());
                    } else//无
                    {
                        singleSubscriber.onSuccess(-1);
                    }

                }
                else {
                    singleSubscriber.onError(new Throwable("get file index error"));
                }
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    public static int getFileIndex(final String file_name) {
        List<FileIndex> list = new Select().from(FileIndex.class).where("file_name = ?", file_name).execute();

        if (list != null) {
            if (list.size() > 0)//有
            {
                return list.get(0).getFile_index();
            } else {
                return -1;
            }

        }
        return -1;
    }

    /**
     * 保存文件最新索引
     */
    public static void saveFileIndex(String file_name, int file_index) {
        FileIndex item = new FileIndex(file_name, file_index);
        item.save();
    }


    /**
     * 保存已经授权的s网盘信息
     *
     * @param inputItem
     */
    public static void saveConnectedInputItem(final InputItem inputItem) {
        inputItem.setConnected(true);
        inputItem.save();
        BusProvider.getInstance().post(new OauthSuccessEvent());
    }

    public static void saveDisconnectedInputItem(String hint, String netDisk) {
        InputItem inputItem = new InputItem(hint, netDisk);
        inputItem.setConnected(false);
        inputItem.save();

        BusProvider.getInstance().post(new OauthSuccessEvent());
    }

    /**
     * 清除wifi傳輸的connect列表
     */
    public static void clearConnectPcList() {
        Single.create(new Single.OnSubscribe<ConnectPc>() {
            @Override
            public void call(SingleSubscriber<? super ConnectPc> singleSubscriber) {
                new Delete().from(ConnectPc.class).execute();
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    /**
     * 初始化网盘信息
     *
     * @param context
     * @return
     */
    public static Subscription initNetDiskInfo(final Context context) {
        return Single.create(new Single.OnSubscribe<Boolean>() {
            @Override
            public void call(SingleSubscriber<? super Boolean> singleSubscriber) {
                new Delete().from(InputItem.class).execute();//清空网盘
                // 初始化网盘数据库表
                InputItem inputItem = new InputItem(context.getString(R.string.connect_to_box_account), context.getString(R.string.box));
                inputItem.save();

                inputItem = new InputItem(context.getString(R.string.connect_to_dropbox_account), context.getString(R.string.dropBox));
                inputItem.save();
                if (!singleSubscriber.isUnsubscribed())
                    singleSubscriber.onSuccess(true);

            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleSubscriber<Boolean>() {
            @Override
            public void onSuccess(Boolean value) {
                //更新input界面
                BusProvider.getInstance().post(new OauthSuccessEvent());
            }

            @Override
            public void onError(Throwable error) {

            }
        });

    }

    /**
     * 获取WIFI传输已连接的pc列表
     *
     * @param singleSubscriber
     * @return
     */
    public static Subscription getConnectPcLists(SingleSubscriber singleSubscriber) {
        return Single.create(new Single.OnSubscribe<List<ConnectPc>>() {
            @Override
            public void call(SingleSubscriber<? super List<ConnectPc>> singleSubscriber) {
                List<ConnectPc> list = new Select().from(ConnectPc.class).execute();
                if (!singleSubscriber.isUnsubscribed() && list != null && !list.isEmpty()) {
                    singleSubscriber.onSuccess(list);
                }
            }
        }).map(new Func1<List<ConnectPc>, List<String>>() {
            @Override
            public List<String> call(List<ConnectPc> connectPcs) {
                List<String> pcNameLists = new ArrayList<>(connectPcs.size());
                for (ConnectPc connectPc : connectPcs) {
                    pcNameLists.add(connectPc.getName());
                }
                return pcNameLists;
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(singleSubscriber);
    }
}
